package com.laicunba.service.impl;

import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import net.sf.json.JSONObject;

import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.laicunba.pojo.RegistryDO;
import com.laicunba.service.MarketingMobileMessageService;
import com.laicunba.service.RegistryService;
import com.laicunba.util.DateUtil;
import com.laicunba.util.MD5Util;
import com.laicunba.util.StringUtil;
import com.laicunba.util.ThreadUtil;
import com.laicunba.util.emay.AES;
import com.laicunba.util.emay.GZIPUtils;
import com.laicunba.util.emay.JsonHelper;
import com.laicunba.util.emay.SmsResponse;
import com.laicunba.util.emay.http.EmayHttpClient;
import com.laicunba.util.emay.http.EmayHttpRequestBytes;
import com.laicunba.util.emay.http.EmayHttpResponseBytes;
import com.laicunba.util.emay.http.EmayHttpResponseBytesPraser;
import com.laicunba.util.emay.http.EmayHttpResultCode;

@Service
public class MarketingMobileMessageServiceImpl implements MarketingMobileMessageService {
	private static final Logger LOG = Logger.getLogger(MarketingMobileMessageServiceImpl.class);
	
	@Autowired
	private RegistryService registryService;

	@Override
	public void sendMsgAsyncByYr(final String mobile, final String msg) {
		RegistryDO yrConfig = registryService.get(RegistryDO.class, "sys.mobile.msg.yr");
		if(yrConfig == null || StringUtil.isEmpty(yrConfig.getVal())) {
			LOG.warn(String.format("短信未发送警告：注册表短信配置为空或内容为空"));
			return;
		}
		JSONObject obj = JSONObject.fromObject(yrConfig.getVal());
		if(obj == null) {
			LOG.warn(String.format("短信未发送警告：注册表短信配置内容为空"));
			return;
		}
		
		final String url = obj.get("url").toString();
		final String account = obj.get("account").toString();
		final String pswd = obj.get("pswd").toString();
		final String mock = obj.get("mock").toString();
//		LOG.info(String.format("云融短信配置:url=%s, account=%s, pswd=%s, mock=%s", url, account, pswd, mock));
		if(StringUtil.isEmpty(url, account, pswd, mock)) {
			LOG.warn(String.format("短信未发送警告:注册表短信配置错误，url=%s, account=%s, pswd=%s, mock=%s", url, account, pswd, mock));
			return;
		}
		
		if (Boolean.valueOf(mock)) {
			LOG.warn(String.format("短信未发送警告:mock被设置为true  手机号码:%s ,短信内容: %s", mobile, msg));
			return;
		}
		ThreadUtil.execute(new Runnable() {

			@Override
			public void run() {
				String postParam = String.format("cmd=sendMessage&userName=%s&passWord=%s&mobilePhone=%s&body=%s", account, pswd, mobile, msg);
				HttpURLConnection conn = null;
				try {
					URL urlObj = new URL(url);
					conn = (HttpURLConnection) urlObj.openConnection();
					conn.setRequestMethod("POST");
					conn.setDoOutput(true);
					conn.getOutputStream().write(postParam.getBytes("utf-8"));
					String result = IOUtils.toString(conn.getInputStream());
					LOG.info(String.format("发送短信完毕  手机号[%s],内容[%s],发送结果[%s]", mobile, msg, result));
				} catch (Exception e) {
					LOG.error("短信发送出错", e);
				} finally {
					conn.disconnect();
				}
			}
		});

	}

	@Override
	public void sendMsgAsyncByYm(final String mobile, final String msg) {
		RegistryDO yrConfig = registryService.get(RegistryDO.class, "sys.mobile.msg.ym");
		if(yrConfig == null || StringUtil.isEmpty(yrConfig.getVal())) {
			LOG.warn(String.format("短信未发送警告：注册表短信配置为空或内容为空"));
			return;
		}
		JSONObject obj = JSONObject.fromObject(yrConfig.getVal());
		if(obj == null) {
			LOG.warn(String.format("短信未发送警告：注册表短信配置内容为空"));
			return;
		}
		
		final String appId = obj.get("appId").toString();
		final String secretKey = obj.get("secretKey").toString();
		final String host = obj.get("host").toString();
		final String algorithm = obj.get("algorithm").toString();
		final String mock = obj.get("mock").toString();
		if(StringUtil.isEmpty(appId, secretKey, host, algorithm, mock)) {
			LOG.warn(String.format("短信未发送警告：注册表短信配置错误，appId=%s, secretKey=%s, host=%s, algorithm=%s, mock=%s", appId, secretKey, host, algorithm, mock));
			return;
		}
		
		if (Boolean.valueOf(mock)) {
			LOG.warn(String.format("短信未发送警告： mock被设置为true  手机号码:%s ,短信内容: %s", mobile, msg));
			return;
		}
		ThreadUtil.execute(new Runnable() {

			@Override
			public void run() {
				Map<String, String> headers = new HashMap<String, String>();
				String timestamp = DateUtil.formatDateTime(new Date());
				String sign = MD5Util.md5((appId + secretKey + timestamp).getBytes()).toString();
				String encode = "UTF-8";
				String url = "http://" + host + "/inter/sendSingleSMS";
				boolean isGzip = false;
				
				LOG.info(String.format("短信开始发送(亿美短信)：appId=%s, sign=%s, timestamp=%s, mobile=%s, content=%s", appId, sign, timestamp, mobile, msg));
				Map<String, String> params = new HashMap<String, String>();
				params.put("appId", appId);
				params.put("sign", sign);
				params.put("timestamp", timestamp);
				params.put("mobile", mobile);
				params.put("content", msg);
				
				EmayHttpRequestBytes request = null;
				try {
					headers.put("appId", appId);
					headers.put("encode", encode);
					String requestJson = JsonHelper.toJsonString(params);
					byte[] bytes = requestJson.getBytes(encode);
					if (isGzip) {
						headers.put("gzip", "on");
						bytes = GZIPUtils.compress(bytes);
					}
					byte[] parambytes = AES.encrypt(bytes, secretKey.getBytes(), algorithm);
					LOG.info(String.format("短信发送请求数据：requestJson=%s, requestDataSize[com]=%s, requestDataSize[en]=%s", requestJson, bytes.length, parambytes.length));
					request = new EmayHttpRequestBytes(url, encode, "POST", headers, null, parambytes);
				} catch (Exception e) {
					LOG.warn(String.format("短信未发送警告：加密异常"));
					e.printStackTrace();
				}
				EmayHttpClient client = new EmayHttpClient();
				String code = null;
				String result = null;
				Map<String, Object> resultMap = new HashMap<String, Object>();
				try {
					EmayHttpResponseBytes res = client.service(request, new EmayHttpResponseBytesPraser());
					if(res == null){
						LOG.warn(String.format("短信未发送警告：请求接口异常"));
						resultMap.put("code", code);
						resultMap.put("result", result);
					}
					if (res.getResultCode().equals(EmayHttpResultCode.SUCCESS)) {
						if (res.getHttpCode() == 200) {
							code = res.getHeaders().get("result");
							if (code.equals("SUCCESS")) {
								byte[] data = res.getResultBytes();
								data = AES.decrypt(data, secretKey.getBytes(), algorithm);
								if (isGzip) {
									data = GZIPUtils.decompress(data);
								}
								result = new String(data, encode);
								LOG.info(String.format("短信发送成功：responseData=%s, responseDataSize[com]=%s, responseJson=%s", data, data.length, result));
							}
						} else {
							LOG.warn(String.format("短信未发送警告：请求接口异常,请求码:" + res.getHttpCode()));
						}
					} else {
						LOG.warn(String.format("短信未发送警告：请求接口网络异常:" + res.getResultCode().getCode()));
					}
				} catch (Exception e) {
					LOG.warn(String.format("短信未发送警告：解析失败"));
					e.printStackTrace();
				}
				resultMap.put("code", code);
				resultMap.put("result", result);
				
				if("SUCCESS".equals(resultMap.get("code"))){
					SmsResponse response = JsonHelper.fromJson(SmsResponse.class, resultMap.get("result").toString());
					if (response != null) {
						LOG.info(String.format("短信发送成功：resultCode=%s, data=%s", resultMap.get("code"), response.getMobile() + "," + response.getSmsId() + "," + response.getCustomSmsId()));
					}
				}
			}
		});

	}

}
